package com.deng.framework.beans.factory.support;

import cn.hutool.core.util.StrUtil;
import com.deng.framework.beans.BeansException;
import com.deng.framework.beans.factory.DisposableBean;
import com.deng.framework.beans.factory.config.BeanDefinition;

import java.lang.reflect.Method;

/**
 *  定义销毁方法适配器
 *  可能你会想这里怎么有一个适配器的类呢，因为销毁方法有两种甚至多种方式，目前有实现接口 DisposableBean、配置信息 destroy-method，两种方式。
 *  而这两种方式的销毁动作是由 AbstractApplicationContext 在注册虚拟机钩子后看，虚拟机关闭前执行的操作动作。
 */
public class DisposableBeanAdapter implements DisposableBean {
    private final Object bean;
    private final String beanName;
    private String destroyMethodName;

    public DisposableBeanAdapter(Object bean, String beanName, BeanDefinition beanDefinition) {
        this.bean = bean;
        this.beanName = beanName;
        this.destroyMethodName = beanDefinition.getDestroyMethodName();
    }

    //适配器方法的实现
    @Override
    public void destroy() throws Exception {
        // 接口方法的实现，即继承了DisposableBean接口的销毁类
        if(bean instanceof DisposableBean){
            ((DisposableBean) bean).destroy();
        }
        // xml配置信息中destory-method的实现
        if(StrUtil.isNotEmpty(destroyMethodName) && !(bean instanceof DisposableBean && "destory".equals(this.destroyMethodName))){
            Method destoryMethod = bean.getClass().getMethod(destroyMethodName);
            if(null == destoryMethod){
                throw new BeansException("error");
            }
            destoryMethod.invoke(bean);
        }
    }
}
